package com.wsl.HealthChallenge.models;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.jdo.JDOHelper;
import javax.jdo.annotations.Key;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.jdo.annotations.Value;

import com.google.appengine.api.datastore.Text;

/**
 * Data model for a Google Health challenge.
 * 
 * TODO(mark): Add a description and an endTime field.
 * 
 * @author mark
 */
@PersistenceCapable
public class ContestEntry {
    /** 
     * The id of the challenge which is also used in the
     * URL for that challenge, e.g. http://www.walk2.me/{id}
     */
    @PrimaryKey
    @Persistent
    private String id;

    /** The name of the challenge. */
    @Persistent
    private String name;

    /** ContestType.stringRepresentation */
    @Persistent
    private String type="";

    @Persistent
    private Text description;

    /** The start date of the challenge. */
    @Persistent
    private Date startDate;

    /** The end date of the challenge. */
    @Persistent
    private Date endDate;

    /** The Google user id of the administrators of this challenge. */
    @Persistent
    private Set<String> adminUserIds;

    /** A map that stores name and score value for each participant of this challenge. */
    @Persistent(serialized = "true", defaultFetchGroup = "true")
    @Key(types=java.lang.String.class)
    @Value(types=com.wsl.HealthChallenge.models.UserStats.class, dependent="true")
    private HashMap<String, UserStats> userStats;

    /**
     * Constructor.
     * @param id The id of the challenge which is also used in the URL for that challenge
     * @param name the name of the challenge
     * @param contestType 
     * @param startDate the start date of the challenge
     * @param endDate the end date of the challenge
     * @param adminUserId the Google user id of the administrator of this challenge
     */
    public ContestEntry(String id, String name, ContestType contestType, Date startDate, Date endDate, String adminUserId) {
        this.id = id;
        this.name = name;
        this.type = contestType.stringRepresentation;
        this.startDate = startDate;
        this.endDate = endDate;
        this.adminUserIds = new HashSet<String>();
        adminUserIds.add(adminUserId);
        this.userStats = new HashMap<String, UserStats>();
    }

    /**
     * @return the id of the challenge which is also used in the URL for that challenge
     */
    public String getId() {
        return id;
    }

    /**
     * @return the name of the challenge
     */
    public String getName() {
        return name;
    }

    /**
     * @return the type of this challenge, e.g. "calories burned", or "steps taken".
     */
    public ContestType getType() {
        //return ContestType.STEPS_TAKEN;
        return ContestType.getFromStringRepresentation(type);
    }

    public void setType(ContestType type) {
        this.type = type.stringRepresentation;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the start date of the challenge
     */
    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    /**
     * @return the end date of the challenge
     */
    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public String getDescription() {
        if (description != null) {
            return description.getValue();            
        } else {
            return null;
        }
    }

    public void setDescription(String description) {
        this.description = new Text(description);
    }

    /**
     * @return the Google user id of the administrator of this challenge
     */
    public boolean isAdminUser(String userId) {
        return adminUserIds.contains(userId);
    }

    public boolean addAdminUser(String userId) {
        if (adminUserIds.add(userId)) {
            JDOHelper.makeDirty(this, "adminUserIds");
            return true;
        }
        return false;
    }

    /**
     * @return a map that stores name and score value for each participant of this challenge.
     */
    public Map<String, UserStats> getUserStats() {
        return userStats;
    }
}